﻿using Mercury.Core.BaseProvider;
using Mercury.Core.Configuration;
using Mercury.Core.DBManager;
using Mercury.Core.Extensions;
using Mercury.Entity.DomainModels;
using Mercury.Entity.SystemModels;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using System.Collections.Concurrent;
using System.Data;

namespace Mercury.Tripartite
{
    public class Param
    {
        /// <summary>
        /// 车号
        /// </summary>
        public string? Serialnumber { get; set; }

        /// <summary>
        /// 认证机型,机型大类
        /// </summary>
        public string? EngineType { get; set; }

        /// <summary>
        /// 机型（供货代码）,机型小类
        /// </summary>
        public string? TPEngineType { get; set; }

        /// <summary>
        /// 内部SN确认
        /// </summary>
        public string? SendTime { get; set; }
    }


    class UPNR
    {
        public string? VIN { get; set; }
        public string? KNR { get; set; }
        public string? Card { get; set; }
        public string? GetDate { get; set; }
    }

    public static class SaveDataExtantion
    {
        private static ConcurrentQueue<UPNR> queueData = new ConcurrentQueue<UPNR>();
        private static string _loggerPath = AppSetting.DownLoadPath + "AddVehicleQueue\\SaveData\\";

        static SaveDataExtantion()
        {
            Task.Run(() =>
            {
                Start();
            }
            );
        }

        private static async void Start()
        {
            var list = new List<UPNR>();
            DataTable queueTable = CreateEmptyTable();
            while (true)
            {
                try
                {
                    if (queueData.Count > 0 && list.Count < 500)
                    {
                        int count = queueData.Count;
                        for (int i = 0; i < count; i++)
                        {
                            queueData.TryDequeue(out UPNR p);
                            if (p == null)
                                break;
                            var temp = list.FirstOrDefault(x => x.VIN == p.VIN);
                            if (temp != null) list.Remove(temp);
                            list.Add(p);
                        }
                        continue;
                    }
                    await Task.Delay(3000);
                    if (list.Count == 0) { continue; }
                    list.ToDataTable(queueTable);
                    var result = await DBServerProvider.SqlDapper.ExcuteNonQueryAsync("PSavePNRData", new { Data = queueTable }, CommandType.StoredProcedure);
                    Info($"当前写入数据【{list.Count}】条！");
                    list.Clear();
                    queueTable.Clear();
                }
                catch (Exception ex)
                {
                    Error("写入异常：" + ex.ToString());
                }
            }
        }


        private static DataTable ToDataTable(this List<UPNR> list, DataTable dt)
        {
            list.ForEach(c => c.ToRow(dt));
            return dt;
        }

        private static void ToRow(this UPNR pnr, DataTable dt)
        {
            DataRow row = dt.NewRow();
            row["VIN"] = pnr.VIN;
            row["KNR"] = pnr.KNR;
            row["Card"] = pnr.Card;
            row["GetDate"] = pnr.GetDate;
            dt.Rows.Add(row);
        }


        private static DataTable CreateEmptyTable()
        {
            DataTable queueTable = new DataTable();
            queueTable.Columns.Add("VIN", typeof(string));
            queueTable.Columns.Add("KNR", typeof(string));
            queueTable.Columns.Add("Card", typeof(string));
            queueTable.Columns.Add("GetDate", typeof(string));
            return queueTable;
        }

        public static dynamic Add(this List<Param> saveData)
        {
            dynamic? result = null;
            if (saveData == null || !saveData.Any())
            {
                result = new { Result = 0, TaskID = "IF01", Message = $"没有需要保存的数据！", ErrCode = "" };
            }
            else
            {
                var model = saveData.FirstOrDefault(c => string.IsNullOrEmpty(c.Serialnumber)
                || string.IsNullOrEmpty(c.SendTime) || string.IsNullOrEmpty(c.EngineType) || string.IsNullOrEmpty(c.TPEngineType));

                if (model != null)
                {
                    result = new { Result = 0, TaskID = "IF01", Message = $"数据【{model.ToJson()}】异常！", ErrCode = "" };
                }
                else
                {
                    foreach (var item in saveData)
                    {
                        queueData.Enqueue(new UPNR()
                        {
                            VIN = item.Serialnumber,
                            KNR = item.Serialnumber?.Substring(2),
                            Card = item.TPEngineType,
                            GetDate = item.SendTime
                        });
                    }
                    result = new { Result = 1, TaskID = "IF01", Message = "", ErrCode = "" };
                }

            }
            Info($"数据：{(saveData?.ToJson() ?? "")} \r\n结果：{result.ToString()}");
            return result;
        }


        private static void Info(string message)
        {
            WriteText(message, "Info");
        }
        private static void Error(string message)
        {
            WriteText(message, "Erorr");
        }
        private static void WriteText(string message, string subDir)
        {
            message = $"{DateTime.Now}\r\n{message}\r\n";
            try
            {
                Mercury.Core.Utilities.FileHelper.WriteFile(_loggerPath + $"{subDir}\\", $"{DateTime.Now.ToString("yyyyMMdd")}.txt", message,true);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"日志写入文件时出错:{ex.Message}");
            }
        }

    }
}